package com.zhangh.summer.admin.support.ds.es.http;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.CookieStore;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;

import javax.net.ssl.SSLContext;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class Client {
    private static final Map<String, PoolingHttpClientConnectionManager> CM_MAP;//http 连接池
    private final static int MAX_CONN_TOTAL  = 500;   //最大链接数
    private final static int MAX_CONN_PER_ROUTE  = 500;//每个域名最大链接数

    static{
        CM_MAP=new HashMap<>();
    }
    /**
     * 获得httpclient
     * @return client
     */
    public static CloseableHttpClient SSLClient(String url){
        String host=getHost(url);
        String hostHead=getHostHead(url);
        String cmKey=hostHead+host;

        PoolingHttpClientConnectionManager cm=CM_MAP.get(cmKey);
        if (null==cm){
            RegistryBuilder registryBuilder= RegistryBuilder.create();
            if (hostHead.equals("https")){
                registryBuilder.register("https", getSSLConnectionSocketFactory());
            }
            registryBuilder.register("http", new PlainConnectionSocketFactory());
            Registry socketFactoryRegistry = registryBuilder.build();
            cm =new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            cm.setMaxTotal(MAX_CONN_TOTAL);
            cm.setDefaultMaxPerRoute(MAX_CONN_PER_ROUTE);
            CM_MAP.put(cmKey,cm);
        }
        CookieStore cookieStore = new BasicCookieStore();
        return HttpClients.custom()
                .setConnectionManager(cm).setDefaultCookieStore(cookieStore)
                .build();
    }

    /**
     *获得 SSLConnectionSocketFactory
     * @return SSLConnectionSocketFactory
     */
    private  static SSLConnectionSocketFactory getSSLConnectionSocketFactory(){
        return new SSLConnectionSocketFactory(getSSLContext(), NoopHostnameVerifier.INSTANCE);
    }

    /**
     * 获得 SSLContext
     * @return SSLContext
     */
    private static  SSLContext  getSSLContext(){
        SSLContext sslContext=null;
        try {
             sslContext = (new SSLContextBuilder()).loadTrustMaterial(null, (chain, authType) -> true).build();
        }catch (Exception e){
            log.error("get SSLContext error:{}",e.getMessage());
            e.printStackTrace();
        }
        return  sslContext;
    }

    private static String getHost(String url){
        return url.substring(url.indexOf("://")+3,url.lastIndexOf("/"));
    }
    private static String getHostHead(String url){
        return url.substring(0,url.indexOf("://"));
    }

}
